#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "Daemon.hpp"
#include <signal.h>

using namespace dsh_tcpserver;
using namespace dsh_protocol;

static void Usage(const std::string &process)
{
    std::cout << "\nUsage: " << process << " port\n"
              << std::endl;
}

void debug(int sock)
{
    std::cout << "test" << std::endl;
}

static Response calculatorHelp(const Request &req) // 拿到结构化的请求，返回结构化的数据
{
    Response resp(0, 0);
    switch (req.op_)
    {
    case '+':
        resp.result_ = req.x_ + req.y_;
        break;
    case '-':
        resp.result_ = req.x_ - req.y_;
        break;
    case '*':
        resp.result_ = req.x_ * req.y_;
        break;
    case '/':
        if (0 == req.y_)
            resp.code_ = 1;
        else
            resp.result_ = req.x_ / req.y_;
        break;
    case '%':
        if (0 == req.y_)
            resp.code_ = 2;
        else
            resp.result_ = req.x_ % req.y_;
        break;
    default:
        resp.code_ = 3;
        break;
    }
    return resp;
}

void calculator(int sock)
{
    // 1.读取数据
    std::string inbuffer;
    while (true)
    {
        // 1.读取数据
        bool res = Recv(sock, &inbuffer); // 读到了一个请求
        if (!res)
            break;
        // std::cout << "inbuffer: " << inbuffer << std::endl;

        // 2.协议解析，获得一个完整的报文
        std::string package = Decode(inbuffer);
        if (package.empty())
            continue;
        // std::cout << "package: " << package << std::endl;

        Request req;
        // 3.反序列化
        req.Deserialize(package);
        logMessage(NORMAL, "%s", package.c_str());         
        // 4.业务逻辑，得到一个结构化的结果         
        Response resp = calculatorHelp(req);       
        // 5.结果序列化
        std::string respString = resp.Serialize(); 
        // std::cout << "respString: " << respString << std::endl;
        // 如果正在写入的时候对端关闭了，那就不能再写入了，此时OS回向进程发送SIGPIPE信号，所以我们设置忽略即可
        
        // 6.在发送之前也要对结果加上len\r\ncode_ result_\r\n
        respString = Encode(respString);
        // std::cout << "encode: " << respString << std::endl; 

        // 7.发送也是有问题的，这个到后面再说
        Send(sock, respString);
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }

    MyDaemon();
    std::unique_ptr<TcpServer> server(new TcpServer(atoi(argv[1])));
    server->BindService(calculator);
    server->Start();

    // Request req(123, 456, '+');
    // std::string s = req.Serialize();
    // std::cout << s << std::endl;

    // Request temp;
    // temp.Deserialize(s);
    // std::cout << temp.x_ << " " << temp.op_ << " " << temp.y_ << std::endl;

    return 0;
}